using Microsoft.EntityFrameworkCore;
using RiceShop.Models;

namespace RiceShop.Services
{
    /// <summary>
    /// 菜单服务接口，定义了菜单管理的基本操作
    /// </summary>
    public interface IMenuService
    {
        /// <summary>
        /// 获取所有菜单列表
        /// </summary>
        /// <returns>菜单列表</returns>
        Task<IEnumerable<Menu>> GetAllMenusAsync();

        /// <summary>
        /// 获取顶级菜单列表
        /// </summary>
        /// <returns>顶级菜单列表</returns>
        Task<IEnumerable<Menu>> GetTopMenusAsync();

        /// <summary>
        /// 根据ID获取菜单信息
        /// </summary>
        /// <param name="id">菜单ID</param>
        /// <returns>菜单信息，如果不存在则返回null</returns>
        Task<Menu?> GetMenuByIdAsync(long id);

        /// <summary>
        /// 创建新菜单
        /// </summary>
        /// <param name="menu">菜单信息</param>
        /// <returns>创建的菜单信息</returns>
        Task<Menu> CreateMenuAsync(Menu menu);

        /// <summary>
        /// 更新菜单信息
        /// </summary>
        /// <param name="id">菜单ID</param>
        /// <param name="menu">更新的菜单信息</param>
        /// <returns>更新后的菜单信息，如果不存在则返回null</returns>
        Task<Menu?> UpdateMenuAsync(long id, Menu menu);

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="id">菜单ID</param>
        /// <returns>是否删除成功</returns>
        Task<bool> DeleteMenuAsync(long id);

        /// <summary>
        /// 根据父级ID获取子菜单列表
        /// </summary>
        /// <param name="parentId">父级菜单ID</param>
        /// <returns>子菜单列表</returns>
        Task<IEnumerable<Menu>> GetMenusByParentIdAsync(long? parentId);
    }

    /// <summary>
    /// 菜单服务实现类，处理菜单相关的业务逻辑
    /// </summary>
    public class MenuService : IMenuService
    {
        private readonly ApplicationDbContext _context;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">数据库上下文</param>
        public MenuService(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<IEnumerable<Menu>> GetAllMenusAsync()
        {
            return await _context.Menus
                .Where(m => !m.menuDeleted)
                .OrderBy(m => m.menuSortNo)
                .ToListAsync();
        }

        public async Task<IEnumerable<Menu>> GetTopMenusAsync()
        {
            return await _context.Menus
                .Where(m => !m.menuDeleted && m.menuParentId == 1)
                .OrderBy(m => m.menuSortNo)
                .ToListAsync();
        }

        public async Task<Menu?> GetMenuByIdAsync(long id)
        {
            return await _context.Menus
                .Where(m => !m.menuDeleted && m.menuId == id)
                .FirstOrDefaultAsync();
        }

        public async Task<Menu> CreateMenuAsync(Menu menu)
        {
            menu.menuCtime = DateTime.Now;
            menu.menuUtime = DateTime.Now;
            menu.menuDeleted = false;

            _context.Menus.Add(menu);
            await _context.SaveChangesAsync();
            return menu;
        }

        public async Task<Menu?> UpdateMenuAsync(long id, Menu menu)
        {
            var existingMenu = await _context.Menus.FindAsync(id);
            if (existingMenu == null || existingMenu.menuDeleted)
                return null;

            existingMenu.menuParentId = menu.menuParentId;
            existingMenu.menuIdCode = menu.menuIdCode;
            existingMenu.menuName = menu.menuName;
            existingMenu.menuIcon = menu.menuIcon;
            existingMenu.menuPath = menu.menuPath;
            existingMenu.menuComponent = menu.menuComponent;
            existingMenu.menuType = menu.menuType;
            existingMenu.menuSortNo = menu.menuSortNo;
            existingMenu.menuAuthority = menu.menuAuthority;
            existingMenu.menuTarget = menu.menuTarget;
            existingMenu.menuIconColor = menu.menuIconColor;
            existingMenu.menuHide = menu.menuHide;
            existingMenu.menuUtime = DateTime.Now;

            await _context.SaveChangesAsync();
            return existingMenu;
        }

        public async Task<bool> DeleteMenuAsync(long id)
        {
            var menu = await _context.Menus.FindAsync(id);
            if (menu == null)
                return false;

            // 检查是否有子菜单
            var hasChildren = await _context.Menus
                .AnyAsync(m => !m.menuDeleted && m.menuParentId == id);
            if (hasChildren)
                return false;

            // 软删除
            menu.menuDeleted = true;
            menu.menuUtime = DateTime.Now;
            await _context.SaveChangesAsync();
            return true;
        }

        public async Task<IEnumerable<Menu>> GetMenusByParentIdAsync(long? parentId)
        {
            return await _context.Menus
                .Where(m => !m.menuDeleted && m.menuParentId == parentId)
                .OrderBy(m => m.menuSortNo)
                .ToListAsync();
        }
    }
}
